#!/usr/bin/ruby -Ku
# -*- coding: utf-8 -*-
require 'test/unit'
require 'm3g'

# -----------------------------------------------------------------
# レイ光線をユーザーが指定する方のpick関数のテスト
# このテストは本当に簡単なテストしてかしていないので
# m3g-viewerあたりを使って別途検証が必要。
# 実際問題これが通ればほぼ問題ないと思われるが。
# -----------------------------------------------------------------


class Test_picking_2 < Test::Unit::TestCase
  def setup
  end

  def teadown
  end

  # ----------------------------------------------------------------------------------------
  # 座標はすべてsample/test-01-simpleと同じ
  # Cameraは0,0,5)でnear=0.1,far=1000
  # Meshは0,0,0)を中心に左上-1,1)、右下1,-1)
  # 内部的にピックはMeshのローカル座標で行われる。
  # レイ光線の方向ベクトルはユーザーが指定した値で、org + dir*t が衝突地点。
  # ----------------------------------------------------------------------------------------
  def test_pick_mesh_by_user
    positions = M3G::VertexArray.new 4, 3, 2
    positions.values[0,4] = [1,-1,0, 1,1,0, -1,-1,0, -1,1,0]

    normals = M3G::VertexArray.new 4, 3, 1
    normals.values[0,4] = [0,0,127, 0,0,127, 0,0,127, 0,0,127]

    vertices = M3G::VertexBuffer.new
    vertices.positions = positions, 1, [0,0,0]
    vertices.normals   = normals

    tris = M3G::TriangleStripArray.new [0,1,2,3], [4]
    app  = M3G::Appearance.new
    mesh = M3G::Mesh.new vertices, tris, app

    cam = M3G::Camera.new
    cam.perspective = 45, 1, 0.1, 100
    cam.look_at 0,0,5, 0,0,0, 0,1,0

    wld = M3G::World.new
    wld.child << mesh
    wld.child << cam
    wld.active_camera = cam

    # レイ光線をユーザーが指定するピック.
    # 方向ベクトルの長さが0.5であることに注意.
    hit, ri = wld.pick -1,         # scope
                       0, 0, 5,    # ox, oy, oz
                       0, 0, -0.5  # dx, dy, dz


    assert_equal true, hit
    assert_equal mesh, ri.intersected

    # near面からメッシュまでの距離 = 10 =5*2)
    assert_in_delta 10.0, ri.distance, 0.0001

    ray = ri.ray

    # レイはユーザー指定の値そのもの
    # org=0,0,5),dir=0,0,-0.5)
    assert_in_delta 0.0,   ray[0], 0.0001  # ox
    assert_in_delta 0.0,   ray[1], 0.0001  # oy
    assert_in_delta 5.0,   ray[2], 0.0001  # oz
    assert_in_delta 0.0,   ray[3], 0.0001  # dx
    assert_in_delta 0.0,   ray[4], 0.0001  # dy
    assert_in_delta -0.5, ray[5], 0.0001  # dz

    # 法線は0,0,1)
    # 法線はchar型で保存しているので誤差が大きい)
    assert_in_delta 0.0,  ri.normal.x, 0.01  # nx
    assert_in_delta 0.0,  ri.normal.y, 0.01  # ny
    assert_in_delta 1.0,  ri.normal.z, 0.01  # nz

    # サブメッシュは0
    assert_equal 0, ri.submesh_index

    # テクスチャーはundefined.
    # (の時は0を返す実装)
    assert_in_delta 0.0, ri.texture[0].s, 0.0001  # s
    assert_in_delta 0.0, ri.texture[0].t, 0.0001  # t

    # 端っこのピック
    # これはヒットしない
    ri  = M3G::RayIntersection.new
    hit, ri = wld.pick -1,     # scope
                   10, 0, 0,   #  ox, oy, oz
                   0,  0, -1   #  dx, dy, dz

    assert_equal false, hit
  end
end

